<template>
  <el-image-viewer v-if="viewerVisible" 
    :url-list="HignSpeedUrls"
    :initial-index="imgcurrentIndex" 
    @close="closeViewerimg" />
  <div class=''>
      <el-form :model="form" label-width="110px" ref="formRef" :rules="rules"
      v-loading="loading">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="进入房间" required prop="roomId">
              <el-select
                  v-model="form.roomId"
                  placeholder="请选择房间"
                  :disabled="isdisabledbtn"
                >
                <!-- :disabled="form.roomId" -->
                <!--  :disabled="form.roomId !== null" -->
                  <el-option
                      v-for="item in RoomList"
                      :key="item.roomId"
                      :label="item.roomName"
                      :value="item.roomId"
                      :disabled="item.isUsing"
                  />
                  <!-- 正在使用的不可进入 -->
                  <!-- :disabled="item.isUsing" -->
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="进入时间" required prop="factIndate">
              <el-date-picker
                  v-model="form.factIndate"
                  type="datetime"
                  placeholder="请选择进入时间"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  style="width:100%"
                  
              />
              <!--:readonly="form.factIndate !== ''"  -->
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="房间是否安全" required prop="roomIsSafe">
              <el-radio-group v-model="form.roomIsSafe">
                  <el-radio-button
                      v-for="item in sys_yes_no"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                      :disabled="isdisabledbtn"
                  />
                  <!-- :disabled="form.roomIsSafe !== '' || form.roomIsSafe !== null" -->
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="涉案人姓名" required>
              <el-input v-model="form.userName" placeholder="请输入姓名" :readonly="form.factIndate!== ''"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="性别">
              <el-radio-group v-model="form.userSex" :disabled="form.factIndate!== ''">
                  <el-radio-button
                      v-for="item in nj_sex"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                  />
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12" class="mb-4">
            <el-form-item label="涉案人身份">
              <el-select
                  v-model="form.userType"
                  placeholder="选择涉案人身份"
                  :disabled="true"
                >
                  <el-option
                      v-for="item in nj_sheanren_type"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                  />
                  <!-- :disabled="form.factIndate!== ''" -->
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24" class="mb-3">
              <el-button type="primary" @click="IdcardBtn" :disabled="isbackmsg">读取身份证</el-button>
          </el-col>
          <el-col v-if="idcard !== ''" :span="12">
              <span>身份证号:{{ idcard }}</span>
          </el-col>
          <el-col v-if="idname !== ''" :span="6">
              <span>姓名:{{ idname }}</span>
          </el-col>
          <el-col :span="24" class="mt-4">
            <el-row style="width: 100%;">
              <el-col :span="10" >
                <el-button v-if="isopenCameraBtn"  type="primary" @click="CameraBtn" class='mb-3'>
                    启动摄像头
                </el-button>
                <el-button v-else type="danger" @click="CloseCameraBtn" class='mb-3'>
                    关闭摄像头
                </el-button>
                <!-- <el-button   type="primary" @click="CameraBtn" class='mb-3'>
                    启动摄像头
                </el-button>
                <el-button  type="danger" @click="CloseCameraBtn" class='mb-3'>
                    关闭摄像头
                </el-button> -->
              </el-col>
              <el-col :span="12">
                <el-button v-if="!isopenCameraBtn" type="primary" @click="SaveCameraBtn" class='mb-3'>
                    拍照
                </el-button>
              </el-col>
              <el-row style="width: 100%;">
                  <el-col :span="22">
                      <div style="width: 422px;height: 302px;border: 1px solid #666666; background: #fff">
                          <canvas ref="videoCanvas" width="420" height="300"></canvas>
                      </div>
                  </el-col>
              </el-row>
              <el-col :span="24" style="display: flex;flex-wrap: wrap;">
                <div class="block" style="width: 110px; height: 110px;position: relative;margin-right: 10px;"
                    v-for="(img, index) in HignSpeedUrls"  @click="clickImage(index)"
                    :key="index">
                    <el-image style="width: 110px; height: 110px;position: relative;"
                      :src="img"
                      fit="contain" 
                      >
                        <template #error>
                            <div class="image-slot">
                                请使用高拍仪
                            </div>
                        </template>
                    </el-image>
                    <el-icon class="me-1 edit-icon" @click="deletHighSpeedImg(index, $event)">
                        <circle-close />
                    </el-icon>
                </div>
              </el-col>
            </el-row>
          </el-col>
          <el-col :span="21">
          </el-col>
          <el-col :span="3">
            <el-button type="primary" @click="submitHandle">保存</el-button>
          </el-col>
        </el-row>
      </el-form>
  </div>
</template>
<script setup>
import { ElMessage } from 'element-plus'
import { Picture as IconPicture } from '@element-plus/icons-vue'
import {getCurrentInstance, onMounted} from "vue";
import {ApplyDetailInfo,ApplyDetailcomeIn} from "@/api/ApplyDetail/ApplyDetail";
import { getUserProfile } from "@/api/system/user";
import {roomStateList} from "@/api/BAApply/BAApply";

import {SignuploadFile,SignDelFile,SignList,SignimageInfo,saveUploadFile} from "@/api/ApplyDetail/ApplyDetail";
import { getPoliceAreaInfo } from "@/api/PoliceAreaManage/PoliceAreaManage";
import { WebSocketService } from "@/utils/websocket";  // 导入 WebSocket 服务
import { set } from '@vueuse/core';
const {proxy} = getCurrentInstance()
const {nj_sex, nj_sheanren_type,sys_yes_no} = proxy.useDict('nj_sex', 'nj_sheanren_type', 'sys_yes_no')


const loading = ref(false)

const isbackmsg = ref(false)

const isopenCameraBtn = ref(true) // 摄像头按钮是否显示

// 新增帧率控制相关变量
const targetFPS = 20; // 目标帧率(可根据需要调整)1秒15帧。可以调整，越高越流畅，但是对内存及  Gpu要求越高
const frameInterval = 1000 / targetFPS; // 每帧间隔(ms)
let lastRenderTime = 0; // 上次渲染时间戳
let frameQueue = []; // 帧队列(最多保留1帧)
let isRendering = false; // 是否正在渲染中
let animationFrameId = null; // requestAnimationFrame ID


const videoCanvas = ref(null); // Canvas DOM 引用
const canvasCtx = ref(null);   // Canvas 2D 上下文

const viewerVisible = ref(false)
const imgcurrentIndex = ref(0);

// 用于关闭预览
const clickImage = (index) => {
  imgcurrentIndex.value = index
    setTimeout(() => {
        viewerVisible.value = true;
    }, 100);
};
// 用于关闭预览
const closeViewerimg = () => {
  viewerVisible.value = false;
};

const idcard = ref('')
const idname = ref('')

const SarSignatureUrl = ref('')
const isHighSpeedValue = ref()
const HignSpeedUrls = ref([])
const HignSpeedSubUploadID = ref([])

const isdisabledbtn = ref(true)

const AreaTypeValue = ref()
const props = defineProps({
data: {
  type: Object,
  required: true, // 如果这个属性是必需的
},
AreaType: {
  type: String,
  required: true, // 如果这个属性是必需的
},

})
const form = ref({
jwApplyDetailId:null,
})
const RoomList = ref([])

const RoomqueryParams = ref({unitId:null,policeAreaType:AreaTypeValue})
const Roompaging = ref({pageNum: 1,pageSize: 99})

const rules = {
  roomId: [{ required: true, message: "房间不能为空", trigger: "blur" }],
  factIndate: [{ required: true, message: "进入时间不能为空", trigger: "blur" }],
  roomIsSafe: [{ required: true, message: "房间是否安全不能为空", trigger: "blur" }],
  userName: [{ required: true, message: "涉案人不能为空", trigger: "blur" }],
}

// WebSocket 服务实例
let webSocketService = null;
const websocketUrl = ref()

// 通知事件
const emit = defineEmits(['updataList'])

onMounted(() => {
  window.addEventListener('beforeunload', cleanup);
  nextTick(() => {
    if (videoCanvas.value) {
        canvasCtx.value = videoCanvas.value.getContext('2d');
        videoCanvas.value.width = '420';
        videoCanvas.value.height = '300';
        console.log("Canvas初始化完成，尺寸:", videoCanvas.value.width, "x", videoCanvas.value.height);
      } else {
        console.error("Canvas元素未找到！");
      }
  })
AreaTypeValue.value = props.AreaType
getPoliceAreaInfos(props.data)
getUserInfo()
if (props.data && props.data.jw_applydetail_id) {
  // 调用接口获取详细数据
  getApplyDetailInfo(props.data.jw_applydetail_id)
}
})
// 获取个人信息
const getUserInfo = async () => {
  await getUserProfile().then(res => {
      RoomqueryParams.value.unitId = res.data.unitId
      getroomStateLists()
  })
}
// 获取办案区ip地址
const getPoliceAreaInfos = async (querydata) => {
  // console.log(querydata,'这里执行了取办案区ip地址，querydata是从列表过来的数据')
  // 这里执行了取办案区ip地址，querydata是从列表过来的数据
getPoliceAreaInfo(querydata.policearea_id).then(res => {
    websocketUrl.value = 'ws://' + res.data.ipAddress + ':' + res.data.port
    // 创建 WebSocket 实例
    webSocketService = new WebSocketService(websocketUrl.value);
    // webSocketService = new WebSocketService('ws://192.168.3.34:18887');
     // 启动 WebSocket 连接
    webSocketService.createWebSocket()
      .then(() => {
        const path = window.location.pathname
        const istrue =  path.includes('/PoliceWork/')
        if(istrue){
            ElMessage.success({
            message: '与终端设备连接成功',
            showClose: true,
        })
        }
      })
      .catch((error) => {
        ElMessage.error({
          message: '与终端连接失败',
          showClose: true,
        })
      });
    // 设置接收到消息时的回调
    webSocketService.setOnMessageCallback(handleWebSocketMessage);
})
}
// 获取房间列表
const getroomStateLists = async () => {
  await roomStateList(RoomqueryParams.value, Roompaging.value).then(res => {
    // 使用 reduce 合并所有的 baseRoomList
    RoomList.value = res.data.reduce((acc, item) => {
      return acc.concat(item.baseRoomList);
    }, []);
  })
}

// 获取详情
const getApplyDetailInfo = async () => {
loading.value = true
  await ApplyDetailInfo(props.data.jw_applydetail_id).then(res => {
    form.value = res.data
    if(form.value.roomId == '' || form.value.roomId == null){
      isdisabledbtn.value = false
    }else{
      isdisabledbtn.value = true
    }
    if(!form.value.roomIsSafe){
      form.value.roomIsSafe = '1'
    }
    const SignQuery = {objectId:props.data.jw_applydetail_id,type:2 }
    SignList(SignQuery).then(res => {
      HignSpeedUrls.value = []
      HignSpeedSubUploadID.value = []
      loading.value = true
      for(var i = 0;i<res.data.length;i++){
        HignSpeedSubUploadID.value[i] = res.data[i].jwUploadId
        const fileType = res.data[i].filename.split('.')[1]
        SignimageInfo(res.data[i].jwUploadId).then(res => {
            const blob = new Blob([res], { type: 'image/' + fileType });
            const BlobUrlListData = URL.createObjectURL(blob);
            HignSpeedUrls.value.push(BlobUrlListData);
            loading.value = false
        })
      }
    })
    
  })
}

// 删除图片
const deletHighSpeedImg = async (index, event) => {
  event.stopPropagation();
  loading.value = true
  console.log(HignSpeedSubUploadID.value[index])
  await SignDelFile(HignSpeedSubUploadID.value[index]).then(res => {
    loading.value = false
      HignSpeedUrls.value.splice(index, 1);
      HignSpeedSubUploadID.value.splice(index, 1);
      proxy.$modal.msgSuccess(`删除成功`)
  })
}
const closewebSocketService = () => {
  if(webSocketService){
    CloseCameraBtn();
    // webSocketService.close()
  }
}
defineExpose({getUserInfo,getApplyDetailInfo,closewebSocketService})
/** 提交按钮 */
function submitHandle() {
  if(isdisabledbtn.value){
    const saveUploadFileList = HignSpeedSubUploadID.value
    console.log(HignSpeedSubUploadID.value)
    if(HignSpeedSubUploadID.value.length == 0){
      return
    }else{
      saveUploadFile(saveUploadFileList).then(res => {
        proxy.$modal.msgSuccess(`保存成功`)
        HignSpeedSubUploadID.value = []
        HignSpeedUrls.value = []
        getApplyDetailInfo(props.data.jw_applydetail_id);
        emit('updataList', 'fromcomeIn',"来了老弟")
        
      })
    }
  }else{
    console.log('isdisabledbtn.value为false的时候，直接执行保存')
    proxy.$refs["formRef"].validate(valid => {
      if (valid) {
        const subdata = {
          jwApplyDetailId:form.value.jwApplydetailId,
          roomId:form.value.roomId,
          factIndate:form.value.factIndate,
          roomIsSafe:form.value.roomIsSafe,
          fileList:HignSpeedSubUploadID.value
        }
        ApplyDetailcomeIn(subdata).then(res => {
          proxy.$modal.msgSuccess(`保存成功`)
          getApplyDetailInfo(props.data.jw_applydetail_id);
          emit('updataList', 'fromcomeIn',"来了老弟")
        })
      }
    });
  }
}

// 发送消息
function SendMes() {
  webSocketService.sendMessage(isHighSpeedValue.value)        //1是签名，2是高拍仪，3是身份证
}
// 身份证点击
async function IdcardBtn() {
  if(isHighSpeedValue.value == 2){
    await CloseCameraBtn()
    // / 创建 WebSocket 实例
      // webSocketService = new WebSocketService('ws://192.168.3.34:18887');
      webSocketService = new WebSocketService(websocketUrl.value);
      // 启动 WebSocket 连接
      webSocketService.createWebSocket()
        .then(() => {
          const path = window.location.pathname
          const istrue =  path.includes('/PoliceWork/')
          if(istrue){
              ElMessage.success({
              message: '与终端设备连接成功',
              showClose: true,
          })
          }
          // 发送消息
          webSocketService.setOnMessageCallback(handleWebSocketMessage);
          webSocketService.sendMessage(3)        //1是签名，2是高拍仪，3是身份证
          isopenCameraBtn.value = true // 摄像头按钮是否显示
          isbackmsg.value = true
        })
        .catch((error) => {
          // proxy.$modal.error(`WebSocket 连接失败: ${error.message}`);
        });

  }else{
    isHighSpeedValue.value = 3
    isbackmsg.value = true
    proxy.$modal.msg("准备读取身份证");
    webSocketService.sendMessage(3)        //1是签名，2是高拍仪，3是身份证
    isopenCameraBtn.value = true // 摄像头按钮是否显示
  }
}

// 点击启动摄像头
function CameraBtn() {
  isHighSpeedValue.value = 2       //1是签名，2是高拍仪，3是身份证
  console.log(webSocketService.ws.readyState)
    if(webSocketService.ws.readyState == 1){
      SendMes()
      isopenCameraBtn.value = false // 摄像头按钮是否显示
    }else{
      // 创建 WebSocket 实例
      webSocketService = new WebSocketService(websocketUrl.value);
      // webSocketService = new WebSocketService('ws://192.168.3.34:18887');
      // 启动 WebSocket 连接
      webSocketService.createWebSocket()
        .then(() => {
          ElMessage.success({
            message: '与终端设备连接成功',
            showClose: true,
          })
          // 设置接收到消息时的回调
          webSocketService.setOnMessageCallback(handleWebSocketMessage);
          // 发送消息
          SendMes()
          isopenCameraBtn.value = false // 摄像头按钮是否显示
        })
        .catch((error) => {
          // proxy.$modal.error(`WebSocket 连接失败: ${error.message}`);
        });
    }
    
}
// 点击关闭摄像头{
  function CloseCameraBtn() {
    webSocketService.sendMessage('closeCamera')
    isopenCameraBtn.value = true // 摄像头按钮是否显示
    // 清空画布
    clearCanvas();
}
// 清空画布的函数
function clearCanvas() {
  if (canvasCtx.value && videoCanvas.value) {
    console.log("清空画布")
    // 清除整个画布
    // 强制重绘（备用方案）
    if (canvasCtx.value) {
      canvasCtx.value.clearRect(0, 0, 
        videoCanvas.value.width, 
        videoCanvas.value.height);
    }
    // 可选：填充白色背景（如果需要）
      canvasCtx.value.fillStyle = '#ffffff';
      canvasCtx.value.fillRect(0, 0, videoCanvas.value.width, videoCanvas.value.height);
  }
}
// 点击保存图片
async function SaveCameraBtn() {
  webSocketService.sendMessage(11) // 1是签名，2是高拍仪，3是身份证
}
// // 高拍仪点击
// function HighSpeedBtn() {
//   isbackmsg.value = true
//   isHighSpeedValue.value = 2
// // 判断浏览器是否支持 WebSocket
//   if(webSocketService){
//     SendMes()
//   }else{
//     // 创建 WebSocket 实例
//     webSocketService = new WebSocketService(websocketUrl.value);
//     // webSocketService = new WebSocketService('ws://192.168.3.88:18887');

//     // 启动 WebSocket 连接
//     webSocketService.createWebSocket()
//       .then(() => {
//         const path = window.location.pathname
//         const istrue =  path.includes('/PoliceWork/')
//         if(istrue){
//             ElMessage.success({
//             message: '与终端设备连接成功',
//             showClose: true,
//         })
//         }
       
//       })
//       .catch((error) => {
//         // proxy.$modal.error(`WebSocket 连接失败: ${error.message}`);
//       });

//     // 设置接收到消息时的回调
//     webSocketService.setOnMessageCallback(handleWebSocketMessage);
//      // 发送消息
//      SendMes()
//   }
// } 

// 处理 WebSocket 消息
function handleWebSocketMessage(message) {
  isbackmsg.value = false
  if (message === 'cancel' || message === 'end') {
        proxy.$modal.msgWarning(`用户${message === 'cancel' ? '取消' : '结束'}了操作`);
        return;
    }
  if(isHighSpeedValue.value == '2'){
    if(typeof message === 'string'){
      try {
            const data = JSON.parse(message);
            if (data.photo) {
                // 处理拍照结果...
                // 创建Base64图片URL
              const imgUrl = `data:image/jpeg;base64,${data.photo}`;
              // 将图片URL添加到HignSpeedUrls数组
              HignSpeedUrls.value.push(imgUrl);
              // 2. 转成 Blob（base64 => binary）
              const byteString = atob(data.photo);
              const arrayBuffer = new ArrayBuffer(byteString.length);
              const uint8Array = new Uint8Array(arrayBuffer);
              for (let i = 0; i < byteString.length; i++) {
                  uint8Array[i] = byteString.charCodeAt(i);
              }
              const blob = new Blob([uint8Array], { type: 'image/jpeg' });

              // 3. 准备上传参数
              const query = {
                  jwApplyDetailId: form.value.jwApplydetailId,
                  md5key: '12313',
                  fileType: '2' // 2人员进入高拍仪
              };

              const formData = new FormData();
              formData.append('file', blob, 'capture.jpg');

              // 4. 调用上传接口
              SignuploadFile(formData, query).then(res => {
                  proxy.$modal.msgSuccess(`照片上传成功`);
                  HignSpeedSubUploadID.value.push(res.msg);
              });
            }
            return; // 拍照逻辑结束后直接返回
        } catch (e) {
            console.warn("非JSON消息:", message);
        }
    }
        // 情况2：视频流的Blob数据
        if (message instanceof Blob) {
            if (frameQueue.length > 0) {
                frameQueue[0] = message;
            } else {
                frameQueue.push(message);
            }
            scheduleRender();
        }
      }else{
        const Carddata = JSON.parse(message)
          if(Carddata.idcard == form.value.userCode && Carddata.name == form.value.userName ){
            idcard.value = Carddata.idcard
            idname.value = Carddata.name
            proxy.$modal.msgSuccess(`身份信息比对成功`)
          }else if(Carddata.name == '用户取消'){
            proxy.$modal.msgWarning(`用户取消了操作`)
          }else{
            proxy.$modal.msgError(`身份信息比对失败`)
          }
        }
}
// 新增的调度渲染函数
function scheduleRender() {
    // 如果已经在渲染或队列为空，则跳过
    if (isRendering || frameQueue.length === 0) return;
    
    const now = performance.now();
    const elapsed = now - lastRenderTime;
    
    // 如果还没到下一帧的渲染时间，延迟执行
    if (elapsed < frameInterval) {
        if (animationFrameId) {
            cancelAnimationFrame(animationFrameId);
        }
        animationFrameId = requestAnimationFrame(() => {
            scheduleRender();
        });
        return;
    }
    
    // 执行渲染
    processRender();
}

// 新增的处理渲染函数
function processRender() {
    if (isRendering || frameQueue.length === 0) return;
    
    isRendering = true;
    const blob = frameQueue.shift();
    lastRenderTime = performance.now();
    
    // 使用Blob创建对象URL
    const url = URL.createObjectURL(blob);
    const img = new Image();
    
    img.onload = () => {
        if (canvasCtx.value) {
            canvasCtx.value.clearRect(0, 0, videoCanvas.value.width, videoCanvas.value.height);
            canvasCtx.value.drawImage(
                img, 
                0, 0, 
                videoCanvas.value.width, 
                videoCanvas.value.height
            );
        }
        
        // 清理资源
        URL.revokeObjectURL(url);
        isRendering = false;
        
        // 检查是否有新帧需要处理
        if (frameQueue.length > 0) {
            scheduleRender();
        }
    };
    
    img.onerror = (e) => {
        console.error("图片加载失败:", e);
        URL.revokeObjectURL(url);
        isRendering = false;
        
        // 即使出错也继续处理下一帧
        if (frameQueue.length > 0) {
            scheduleRender();
        }
    };
    img.src = url;
}
// 统一的清理函数
const cleanup = () => {
  CloseCameraBtn();
  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId);
    animationFrameId = null; // 重置为null
  }
  frameQueue = [];
  if (webSocketService) {
    // webSocketService.close();
    webSocketService = null; // 重置为null
  }
};

// 组件卸载前的处理
onBeforeUnmount(() => {
  cleanup();
});

onUnmounted(() => {
  window.removeEventListener('beforeunload', cleanup);
});

</script>
<style>
.demo-image__error .block {
padding: 30px 0;
text-align: center;
border-right: solid 1px var(--el-border-color);
display: inline-block;
width: 49%;
box-sizing: border-box;
vertical-align: top;
}
.demo-image__error .demonstration {
display: block;
color: var(--el-text-color-secondary);
font-size: 18px;
margin-bottom: 20px;
}
.demo-image__error .el-image {
max-width: 300px;
max-height: 200px;
width: 100%;
height: 200px;
}

.demo-image__error .image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: var(--el-fill-color-light);
color: var(--el-text-color-secondary);
font-size: 16px;
}
.demo-image__error .image-slot .el-icon {
font-size: 16px;
}

.demo-image__error {
display: flex;
gap: 10px;
}


.demo-image__error {
display: flex;
gap: 10px;
}

.edit-icon {
position: absolute;
top: 0px;
right: -10px;
cursor: pointer;
color: rgba(0, 0, 0, 0.7);
font-size: 20px;
}

.edit-icon:hover {
color: rgba(0, 0, 0, 1);
}
</style>